技巧105 给重要的容器更多CPU

宿主机上的容器一般在竞争的时候平分CPU使用。读者已经了解了如何做出绝对监管或限制,但是那些有点儿太不灵活了。如果想让一个进程比其他进程使用更多的 CPU,一直为它保留整个内核就太浪费了。如果只有几个内核,这样做难免受限制。

对于想把应用程序部署到共享服务器的用户,Docker 创造了多租户的便利条件。这可能会导致在有经验的虚拟机用户中有名的“吵闹的邻居”问题,一个用户耗尽了所有的资源,影响了正在在同一硬件上工作的其他虚拟机。

一个具体的例子是,在写本书时,我们不得不采用这个功能来减少一个尤其贪得无厌的Postgres应用程序的资源占用,它耗尽了CPU周期,让Web服务器无法为终端用户服务。

问题

想要给重要的容器更多的CPU份额,或者把一些容器标记为不那么重要。

解决方案

docker run 命令使用 -c/--cpu-shares 参数,以定义CPU相对使用份额。

当一个容器启动起来的时候,它会得到一个 CPU 份额 的数值(默认是 1024)。当只有一个进程在运行的时候,如果有必要它对CPU可以有100%的使用权,不管它有多少的CPU份额。只有当和其他容器竞争CPU的时候,这个数值才有用。

设想我们有3台容器(A、B和C)同时都在试图使用所有可用的CPU资源:

  • 如果它们的CPU份额相等,那么每个都可以分配到1/3的CPU;
  • 如果A和B拿到512,C拿到1024,那么C获得CPU的一半,A和B各得1/4;
  • 如果A拿到10,B拿到100,C拿到1000,A拿到可用CPU资源的1%不到,并且只有在B和C空闲的时候才能做一些资源消耗较大的事。

以上所有都假设容器可以使用机器上的所有内核(或者只有一个内核)。Docker会尽量把来自容器的负载分配到所有的内核上。如果有两个容器在一个双核机器上运行着单线程应用程序,那么明显无法在应用相对权重的同时最大化使用可用资源。每个容器都会分配到一个在其上执行的内核,不管其权重是多少。

如果想试一下,执行代码清单15-4所示的命令。

代码清单15-4 限制Docker shell的CPU使用

docker run --cpuset-cpus=0 -c 10000 ubuntu:14.04 \
sh -c 'cat /dev/zero > /dev/null' &
docker run --cpuset-cpus=0 -c 1 -it ubuntu:14.04 bash

现在看看在bash里执行操作是多么缓慢。注意,这些数值是相对的,可以把它们全部乘10(举例来说),它们代表的意思仍旧完全相同。但默认得到的仍然是 1024,所以当修改这些数值的时候,应当考虑一下在同一套CPU上运行一个没有指定份额的进程会怎么样。

提示

为用例选择合适的CPU份额层是一门艺术。值得看一下top和vmstat一类程序的输出,看看什么在用CPU时间。使用top的时候,按“1”键展示每个CPU内核各自在做什么尤其有用。

讨论

尽管我们在现实世界中不常看到这种策略直接应用,但是在底层平台还是普遍存在的。当有租户抱怨无法获取资源(或者表现为无法获取资源)的时候,了解并掌握这些底层架构如何工作是很有好处的。在现实世界中这时有发生,尤其是当租户的工作负载对基础设施的不稳定较为敏感的时候。

results matching ""

    No results matching ""